from fastapi import APIRouter, Depends, HTTPException, Query, UploadFile, File
from sqlalchemy.orm import Session
from typing import Optional, List, Dict, Any, Union
from datetime import datetime
import os

from models.detection_log import DetectionLog as DetectionLogModel
from models.drone import Drone
from models.task import Task
from models.detection_target import DetectionTarget
from models.detection_model import DetectionModel, ModelVersion
from schemas.detection_log import (
    DetectionLog, DetectionLogCreate, DetectionLogUpdate, 
    DetectionLogList, DetectionLogDetail, DetectionLogStatistics
)
from database import get_db

router = APIRouter()


@router.post("/", response_model=DetectionLog)
def create_detection_log(
    detection_log: DetectionLogCreate,
    db: Session = Depends(get_db)
):
    """
    创建检测日志
    
    - **drone_id**: 无人机ID（必填）
    - **latitude/longitude/altitude**: 检测位置（必填）
    - **confidence**: 置信度（必填，0-100）
    - **photo_path**: 照片路径（可选）
    - 其他字段为可选
    """
    try:
        # 验证无人机是否存在
        drone = db.query(Drone).filter(Drone.id == detection_log.drone_id).first()
        if not drone:
            raise HTTPException(status_code=404, detail="无人机不存在")
        
        # 验证关联的实体是否存在
        if detection_log.task_id:
            task = db.query(Task).filter(Task.id == detection_log.task_id).first()
            if not task:
                raise HTTPException(status_code=404, detail="任务不存在")
        
        if detection_log.detection_target_id:
            target = db.query(DetectionTarget).filter(DetectionTarget.id == detection_log.detection_target_id).first()
            if not target:
                raise HTTPException(status_code=404, detail="检测目标不存在")
        
        if detection_log.detection_model_id:
            model = db.query(DetectionModel).filter(DetectionModel.id == detection_log.detection_model_id).first()
            if not model:
                raise HTTPException(status_code=404, detail="检测模型不存在")
        
        if detection_log.model_version_id:
            version = db.query(ModelVersion).filter(ModelVersion.id == detection_log.model_version_id).first()
            if not version:
                raise HTTPException(status_code=404, detail="模型版本不存在")
        
        # 创建检测日志
        db_detection_log = DetectionLogModel(**detection_log.model_dump())
        db.add(db_detection_log)
        db.commit()
        db.refresh(db_detection_log)
        
        # 构建响应
        response = DetectionLog(
            id=db_detection_log.id,
            drone_id=db_detection_log.drone_id,
            drone_name=drone.name,
            task_id=db_detection_log.task_id,
            task_name=task.name if detection_log.task_id and task else None,
            flight_log_id=db_detection_log.flight_log_id,
            detection_target_id=db_detection_log.detection_target_id,
            target_name=target.name if detection_log.detection_target_id and target else None,
            detection_model_id=db_detection_log.detection_model_id,
            model_name=model.name if detection_log.detection_model_id and model else None,
            model_version_id=db_detection_log.model_version_id,
            model_version_name=version.version_name if detection_log.model_version_id and version else None,
            latitude=db_detection_log.latitude,
            longitude=db_detection_log.longitude,
            altitude=db_detection_log.altitude,
            confidence=db_detection_log.confidence,
            detection_result=db_detection_log.detection_result,
            is_positive=db_detection_log.is_positive,
            detection_time=db_detection_log.detection_time,
            photo_time=db_detection_log.photo_time,
            photo_path=db_detection_log.photo_path,
            photo_thumbnail_path=db_detection_log.photo_thumbnail_path,
            photo_metadata=db_detection_log.photo_metadata,
            notes=db_detection_log.notes,
            processed=db_detection_log.processed,
            created_at=db_detection_log.created_at,
            updated_at=db_detection_log.updated_at
        )
        
        return response
        
    except HTTPException:
        raise
    except Exception as e:
        db.rollback()
        raise HTTPException(status_code=500, detail=f"创建检测日志失败: {str(e)}")


@router.get("/", response_model=DetectionLogList)
def get_detection_logs(
    db: Session = Depends(get_db),
    page: int = Query(1, ge=1, description="页码"),
    page_size: int = Query(10, ge=1, le=100, description="每页数量"),
    drone_id: Union[str, int, None] = Query(None, description="无人机ID"),
    task_id: Union[str, int, None] = Query(None, description="任务ID"),
    detection_target_id: Union[str, int, None] = Query(None, description="检测目标ID"),
    start_time: Optional[datetime] = Query(None, description="开始时间"),
    end_time: Optional[datetime] = Query(None, description="结束时间"),
    is_positive: Optional[bool] = Query(None, description="是否为正样本"),
    processed: Optional[bool] = Query(None, description="是否已处理")
):
    """
    获取检测日志列表
    
    支持按无人机、任务、检测目标、时间范围、检测结果等筛选
    """
    try:
        # 处理空字符串输入
        if drone_id == "":
            drone_id = None
        elif drone_id is not None:
            drone_id = int(drone_id)
            
        if task_id == "":
            task_id = None
        elif task_id is not None:
            task_id = int(task_id)
            
        if detection_target_id == "":
            detection_target_id = None
        elif detection_target_id is not None:
            detection_target_id = int(detection_target_id)
    
        # 构建查询
        query = db.query(
            DetectionLogModel,
            Drone.name.label('drone_name'),
            Task.name.label('task_name'),
            DetectionTarget.name.label('target_name'),
            DetectionModel.name.label('model_name'),
            ModelVersion.version_name.label('model_version_name')
        ).join(
            Drone, DetectionLogModel.drone_id == Drone.id,
            isouter=True
        ).join(
            Task, DetectionLogModel.task_id == Task.id,
            isouter=True
        ).join(
            DetectionTarget, DetectionLogModel.detection_target_id == DetectionTarget.id,
            isouter=True
        ).join(
            DetectionModel, DetectionLogModel.detection_model_id == DetectionModel.id,
            isouter=True
        ).join(
            ModelVersion, DetectionLogModel.model_version_id == ModelVersion.id,
            isouter=True
        )
        
        # 应用筛选条件
        if drone_id:
            query = query.filter(DetectionLogModel.drone_id == drone_id)
        if task_id:
            query = query.filter(DetectionLogModel.task_id == task_id)
        if detection_target_id:
            query = query.filter(DetectionLogModel.detection_target_id == detection_target_id)
        if start_time:
            query = query.filter(DetectionLogModel.detection_time >= start_time)
        if end_time:
            query = query.filter(DetectionLogModel.detection_time <= end_time)
        if is_positive is not None:
            query = query.filter(DetectionLogModel.is_positive == is_positive)
        if processed is not None:
            query = query.filter(DetectionLogModel.processed == processed)
        
        # 计算总数
        total = query.count()
        
        # 分页查询
        offset = (page - 1) * page_size
        results = query.order_by(
            DetectionLogModel.detection_time.desc()
        ).offset(offset).limit(page_size).all()
        
        # 构建响应数据
        items = []
        for log, drone_name, task_name, target_name, model_name, model_version_name in results:
            item = {
                "id": log.id,
                "drone_id": log.drone_id,
                "drone_name": drone_name,
                "task_id": log.task_id,
                "task_name": task_name,
                "detection_target_id": log.detection_target_id,
                "target_name": target_name,
                "detection_model_id": log.detection_model_id,
                "model_name": model_name,
                "model_version_id": log.model_version_id,
                "model_version_name": model_version_name,
                "latitude": log.latitude,
                "longitude": log.longitude,
                "altitude": log.altitude,
                "confidence": log.confidence,
                "is_positive": log.is_positive,
                "detection_time": log.detection_time.isoformat() if log.detection_time else None,
                "photo_time": log.photo_time.isoformat() if log.photo_time else None,
                "photo_path": log.photo_path,
                "processed": log.processed,
                "created_at": log.created_at.isoformat()
            }
            items.append(item)
        
        return {
            "code": 200,
            "message": "获取成功",
            "data": {
                "items": items,
                "total": total,
                "page": page,
                "page_size": page_size,
                "pages": (total + page_size - 1) // page_size
            }
        }
        
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取检测日志失败: {str(e)}")


@router.get("/{detection_log_id}", response_model=DetectionLogDetail)
def get_detection_log(
    detection_log_id: int,
    db: Session = Depends(get_db)
):
    """
    获取检测日志详情
    """
    try:
        # 查询检测日志
        log = db.query(DetectionLogModel).filter(DetectionLogModel.id == detection_log_id).first()
        if not log:
            raise HTTPException(status_code=404, detail="检测日志不存在")
        
        # 获取关联信息
        drone = db.query(Drone).filter(Drone.id == log.drone_id).first()
        task = db.query(Task).filter(Task.id == log.task_id).first() if log.task_id else None
        target = db.query(DetectionTarget).filter(DetectionTarget.id == log.detection_target_id).first() if log.detection_target_id else None
        model = db.query(DetectionModel).filter(DetectionModel.id == log.detection_model_id).first() if log.detection_model_id else None
        version = db.query(ModelVersion).filter(ModelVersion.id == log.model_version_id).first() if log.model_version_id else None
        
        # 构建响应
        detection_log = DetectionLog(
            id=log.id,
            drone_id=log.drone_id,
            drone_name=drone.name if drone else None,
            task_id=log.task_id,
            task_name=task.name if task else None,
            flight_log_id=log.flight_log_id,
            detection_target_id=log.detection_target_id,
            target_name=target.name if target else None,
            detection_model_id=log.detection_model_id,
            model_name=model.name if model else None,
            model_version_id=log.model_version_id,
            model_version_name=version.version_name if version else None,
            latitude=log.latitude,
            longitude=log.longitude,
            altitude=log.altitude,
            confidence=log.confidence,
            detection_result=log.detection_result,
            is_positive=log.is_positive,
            detection_time=log.detection_time,
            photo_time=log.photo_time,
            photo_path=log.photo_path,
            photo_thumbnail_path=log.photo_thumbnail_path,
            photo_metadata=log.photo_metadata,
            notes=log.notes,
            processed=log.processed,
            created_at=log.created_at,
            updated_at=log.updated_at
        )
        
        return {
            "code": 200,
            "message": "获取成功",
            "data": detection_log
        }
        
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取检测日志详情失败: {str(e)}")


@router.put("/{detection_log_id}", response_model=DetectionLog)
def update_detection_log(
    detection_log_id: int,
    detection_log_update: DetectionLogUpdate,
    db: Session = Depends(get_db)
):
    """
    更新检测日志
    """
    try:
        # 查询检测日志
        log = db.query(DetectionLogModel).filter(DetectionLogModel.id == detection_log_id).first()
        if not log:
            raise HTTPException(status_code=404, detail="检测日志不存在")
        
        # 验证更新的关联实体是否存在
        if detection_log_update.task_id is not None:
            task = db.query(Task).filter(Task.id == detection_log_update.task_id).first()
            if not task and detection_log_update.task_id is not None:
                raise HTTPException(status_code=404, detail="任务不存在")
        
        if detection_log_update.detection_target_id is not None:
            target = db.query(DetectionTarget).filter(DetectionTarget.id == detection_log_update.detection_target_id).first()
            if not target and detection_log_update.detection_target_id is not None:
                raise HTTPException(status_code=404, detail="检测目标不存在")
        
        if detection_log_update.detection_model_id is not None:
            model = db.query(DetectionModel).filter(DetectionModel.id == detection_log_update.detection_model_id).first()
            if not model and detection_log_update.detection_model_id is not None:
                raise HTTPException(status_code=404, detail="检测模型不存在")
        
        if detection_log_update.model_version_id is not None:
            version = db.query(ModelVersion).filter(ModelVersion.id == detection_log_update.model_version_id).first()
            if not version and detection_log_update.model_version_id is not None:
                raise HTTPException(status_code=404, detail="模型版本不存在")
        
        # 更新字段
        update_data = detection_log_update.model_dump(exclude_unset=True)
        for field, value in update_data.items():
            setattr(log, field, value)
        
        db.commit()
        db.refresh(log)
        
        # 获取关联信息
        drone = db.query(Drone).filter(Drone.id == log.drone_id).first()
        task = db.query(Task).filter(Task.id == log.task_id).first() if log.task_id else None
        target = db.query(DetectionTarget).filter(DetectionTarget.id == log.detection_target_id).first() if log.detection_target_id else None
        model = db.query(DetectionModel).filter(DetectionModel.id == log.detection_model_id).first() if log.detection_model_id else None
        version = db.query(ModelVersion).filter(ModelVersion.id == log.model_version_id).first() if log.model_version_id else None
        
        # 构建响应
        response = DetectionLog(
            id=log.id,
            drone_id=log.drone_id,
            drone_name=drone.name if drone else None,
            task_id=log.task_id,
            task_name=task.name if task else None,
            flight_log_id=log.flight_log_id,
            detection_target_id=log.detection_target_id,
            target_name=target.name if target else None,
            detection_model_id=log.detection_model_id,
            model_name=model.name if model else None,
            model_version_id=log.model_version_id,
            model_version_name=version.version_name if version else None,
            latitude=log.latitude,
            longitude=log.longitude,
            altitude=log.altitude,
            confidence=log.confidence,
            detection_result=log.detection_result,
            is_positive=log.is_positive,
            detection_time=log.detection_time,
            photo_time=log.photo_time,
            photo_path=log.photo_path,
            photo_thumbnail_path=log.photo_thumbnail_path,
            photo_metadata=log.photo_metadata,
            notes=log.notes,
            processed=log.processed,
            created_at=log.created_at,
            updated_at=log.updated_at
        )
        
        return response
        
    except HTTPException:
        raise
    except Exception as e:
        db.rollback()
        raise HTTPException(status_code=500, detail=f"更新检测日志失败: {str(e)}")


@router.delete("/{detection_log_id}", response_model=Dict[str, Any])
def delete_detection_log(
    detection_log_id: int,
    db: Session = Depends(get_db)
):
    """
    删除检测日志
    """
    try:
        # 查询检测日志
        log = db.query(DetectionLogModel).filter(DetectionLogModel.id == detection_log_id).first()
        if not log:
            raise HTTPException(status_code=404, detail="检测日志不存在")
        
        # 删除日志（如果需要，也可以删除相关的照片文件）
        db.delete(log)
        db.commit()
        
        return {
            "code": 200,
            "message": "删除成功"
        }
        
    except HTTPException:
        raise
    except Exception as e:
        db.rollback()
        raise HTTPException(status_code=500, detail=f"删除检测日志失败: {str(e)}")


@router.get("/statistics/overview", response_model=DetectionLogStatistics)
def get_detection_statistics(
    drone_id: Union[str, int, None] = Query(None, description="无人机ID"),
    task_id: Union[str, int, None] = Query(None, description="任务ID"),
    detection_target_id: Union[str, int, None] = Query(None, description="检测目标ID"),
    start_time: Optional[datetime] = Query(None, description="开始时间"),
    end_time: Optional[datetime] = Query(None, description="结束时间"),
    db: Session = Depends(get_db)
):
    """
    获取检测统计数据
    
    包括检测总数、正样本数、平均置信度等统计信息
    """
    try:
        # 处理空字符串输入
        if drone_id == "":
            drone_id = None
        elif drone_id is not None:
            drone_id = int(drone_id)
            
        if task_id == "":
            task_id = None
        elif task_id is not None:
            task_id = int(task_id)
            
        if detection_target_id == "":
            detection_target_id = None
        elif detection_target_id is not None:
            detection_target_id = int(detection_target_id)
    
        # 构建查询
        query = db.query(DetectionLogModel)
        
        # 应用筛选条件
        if drone_id:
            query = query.filter(DetectionLogModel.drone_id == drone_id)
        if task_id:
            query = query.filter(DetectionLogModel.task_id == task_id)
        if detection_target_id:
            query = query.filter(DetectionLogModel.detection_target_id == detection_target_id)
        if start_time:
            query = query.filter(DetectionLogModel.detection_time >= start_time)
        if end_time:
            query = query.filter(DetectionLogModel.detection_time <= end_time)
        
        # 获取所有符合条件的日志
        logs = query.all()
        
        if not logs:
            return {
                "code": 200,
                "message": "获取成功",
                "data": {
                    "total_count": 0,
                    "positive_count": 0,
                    "negative_count": 0,
                    "avg_confidence": 0,
                    "max_confidence": 0,
                    "min_confidence": 0,
                    "processed_count": 0,
                    "unprocessed_count": 0,
                    "target_distribution": {},
                    "drone_distribution": {}
                }
            }
        
        # 计算统计数据
        total_count = len(logs)
        positive_count = sum(1 for log in logs if log.is_positive)
        negative_count = total_count - positive_count
        
        confidences = [log.confidence for log in logs]
        avg_confidence = sum(confidences) / total_count if confidences else 0
        max_confidence = max(confidences) if confidences else 0
        min_confidence = min(confidences) if confidences else 0
        
        processed_count = sum(1 for log in logs if log.processed)
        unprocessed_count = total_count - processed_count
        
        # 计算目标分布
        target_distribution = {}
        for log in logs:
            target_id = log.detection_target_id
            if target_id not in target_distribution:
                target_distribution[target_id] = 0
            target_distribution[target_id] += 1
        
        # 计算无人机分布
        drone_distribution = {}
        for log in logs:
            drone_id = log.drone_id
            if drone_id not in drone_distribution:
                drone_distribution[drone_id] = 0
            drone_distribution[drone_id] += 1
        
        return {
            "code": 200,
            "message": "获取成功",
            "data": {
                "total_count": total_count,
                "positive_count": positive_count,
                "negative_count": negative_count,
                "avg_confidence": round(avg_confidence, 2),
                "max_confidence": max_confidence,
                "min_confidence": min_confidence,
                "processed_count": processed_count,
                "unprocessed_count": unprocessed_count,
                "target_distribution": target_distribution,
                "drone_distribution": drone_distribution
            }
        }
        
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取检测统计失败: {str(e)}")